﻿#include "ClientData.h"

ClientMagic::ClientMagic()
{
}

ClientMagic::ClientMagic(BinaryReader *reader)
{
    Name = reader->ReadString();
    Spell = static_cast<Spell>(reader->ReadByte());

    BaseCost = reader->ReadByte();
    LevelCost = reader->ReadByte();
    Icon = reader->ReadByte();
    Level1 = reader->ReadByte();
    Level2 = reader->ReadByte();
    Level3 = reader->ReadByte();
    Need1 = reader->ReadUInt16();
    Need2 = reader->ReadUInt16();
    Need3 = reader->ReadUInt16();

    Level = reader->ReadByte();
    Key = reader->ReadByte();
    Experience = reader->ReadUInt16();

    Delay = reader->ReadInt64();

    Range = reader->ReadByte();
    CastTime = reader->ReadInt64();
}

void ClientMagic::Save(BinaryWriter *writer)
{
    writer->Write(Name);
    writer->Write(static_cast<unsigned char>(Spell));

    writer->Write(BaseCost);
    writer->Write(LevelCost);
    writer->Write(Icon);
    writer->Write(Level1);
    writer->Write(Level2);
    writer->Write(Level3);
    writer->Write(Need1);
    writer->Write(Need2);
    writer->Write(Need3);

    writer->Write(Level);
    writer->Write(Key);
    writer->Write(Experience);

    writer->Write(Delay);

    writer->Write(Range);
    writer->Write(CastTime);
}

ClientRecipeInfo::ClientRecipeInfo()
{
}

ClientRecipeInfo::ClientRecipeInfo(BinaryReader *reader)
{
    Gold = reader->ReadUInt32();
    Chance = reader->ReadByte();

    Item = new UserItem(reader);

    int count = reader->ReadInt32();
    for (int i = 0; i < count; i++)
    {
        UserItem tempVar(reader);
        Tools.push_back(&tempVar);
    }

    count = reader->ReadInt32();
    for (int i = 0; i < count; i++)
    {
        UserItem tempVar2(reader);
        Ingredients.push_back(&tempVar2);
    }
}

void ClientRecipeInfo::Save(BinaryWriter *writer)
{
    writer->Write(Gold);
    writer->Write(Chance);
    Item->Save(writer);

    writer->Write(Tools.size());
    for (auto tool : Tools)
    {
        tool->Save(writer);
    }

    writer->Write(Ingredients.size());
    for (auto ingredient : Ingredients)
    {
        ingredient->Save(writer);
    }
}

ClientFriend::ClientFriend()
{
}

ClientFriend::ClientFriend(BinaryReader *reader)
{
    Index = reader->ReadInt32();
    Name = reader->ReadString();
    Memo = reader->ReadString();
    Blocked = reader->ReadBoolean();

    Online = reader->ReadBoolean();
}

void ClientFriend::Save(BinaryWriter *writer)
{
    writer->Write(Index);
    writer->Write(Name);
    writer->Write(Memo);
    writer->Write(Blocked);

    writer->Write(Online);
}

ClientMail::ClientMail()
{
}

ClientMail::ClientMail(BinaryReader *reader)
{
    MailID = reader->ReadUInt64();
    SenderName = reader->ReadString();
    Message = reader->ReadString();
    Opened = reader->ReadBoolean();
    Locked = reader->ReadBoolean();
    CanReply = reader->ReadBoolean();
    Collected = reader->ReadBoolean();

    DateSent = DateTime::FromBinary(reader->ReadInt64());

    Gold = reader->ReadUInt32();
    int count = reader->ReadInt32();

    for (int i = 0; i < count; i++)
    {
        UserItem tempVar(reader);
        Items.push_back(&tempVar);
    }
}

void ClientMail::Save(BinaryWriter *writer)
{
    writer->Write(MailID);
    writer->Write(SenderName);
    writer->Write(Message);
    writer->Write(Opened);
    writer->Write(Locked);
    writer->Write(CanReply);
    writer->Write(Collected);

    writer->Write(DateSent.ToBinary());

    writer->Write(Gold);
    writer->Write(Items.size());

    for (int i = 0; i < Items.size(); i++)
    {
        Items[i]->Save(writer);
    }
}

ClientAuction::ClientAuction()
{
}

ClientAuction::ClientAuction(BinaryReader *reader)
{
    AuctionID = reader->ReadUInt64();
    Item = new UserItem(reader);
    Seller = reader->ReadString();
    Price = reader->ReadUInt32();
    ConsignmentDate = DateTime::FromBinary(reader->ReadInt64());
    ItemType = static_cast<MarketItemType>(reader->ReadByte());
}

void ClientAuction::Save(BinaryWriter *writer)
{
    writer->Write(AuctionID);
    Item->Save(writer);
    writer->Write(Seller);
    writer->Write(Price);
    writer->Write(ConsignmentDate.ToBinary());
    writer->Write(static_cast<unsigned char>(ItemType));
}

bool ClientQuestInfo::getSameFinishNPC() const
{
    return NPCIndex == FinishNPCIndex;
}

ClientQuestInfo::ClientQuestInfo()
{
}

ClientQuestInfo::ClientQuestInfo(BinaryReader *reader)
{
    Index = reader->ReadInt32();
    NPCIndex = reader->ReadUInt32();
    Name = reader->ReadString();
    Group = reader->ReadString();

    int count = reader->ReadInt32();
    for (int i = 0; i < count; i++)
    {
        Description.push_back(reader->ReadString());
    }

    count = reader->ReadInt32();
    for (int i = 0; i < count; i++)
    {
        TaskDescription.push_back(reader->ReadString());
    }

    count = reader->ReadInt32();
    for (int i = 0; i < count; i++)
    {
        CompletionDescription.push_back(reader->ReadString());
    }

    MinLevelNeeded = reader->ReadInt32();
    MaxLevelNeeded = reader->ReadInt32();
    QuestNeeded = reader->ReadInt32();
    ClassNeeded = static_cast<RequiredClass>(reader->ReadByte());
    Type = static_cast<QuestType>(reader->ReadByte());
    RewardGold = reader->ReadUInt32();
    RewardExp = reader->ReadUInt32();
    RewardCredit = reader->ReadUInt32();

    count = reader->ReadInt32();

    for (int i = 0; i < count; i++)
    {
        QuestItemReward tempVar(reader);
        RewardsFixedItem.push_back(&tempVar);
    }

    count = reader->ReadInt32();

    for (int i = 0; i < count; i++)
    {
        QuestItemReward tempVar2(reader);
        RewardsSelectItem.push_back(&tempVar2);
    }

    FinishNPCIndex = reader->ReadUInt32();
}

void ClientQuestInfo::Save(BinaryWriter *writer)
{
    writer->Write(Index);
    writer->Write(NPCIndex);
    writer->Write(Name);
    writer->Write(Group);

    writer->Write(Description.size());
    for (int i = 0; i < Description.size(); i++)
    {
        writer->Write(Description[i]);
    }

    writer->Write(TaskDescription.size());
    for (int i = 0; i < TaskDescription.size(); i++)
    {
        writer->Write(TaskDescription[i]);
    }

    writer->Write(CompletionDescription.size());
    for (int i = 0; i < CompletionDescription.size(); i++)
    {
        writer->Write(CompletionDescription[i]);
    }

    writer->Write(MinLevelNeeded);
    writer->Write(MaxLevelNeeded);
    writer->Write(QuestNeeded);
    writer->Write(static_cast<unsigned char>(ClassNeeded));
    writer->Write(static_cast<unsigned char>(Type));
    writer->Write(RewardGold);
    writer->Write(RewardExp);
    writer->Write(RewardCredit);

    writer->Write(RewardsFixedItem.size());

    for (int i = 0; i < RewardsFixedItem.size(); i++)
    {
        RewardsFixedItem[i]->Save(writer);
    }

    writer->Write(RewardsSelectItem.size());

    for (int i = 0; i < RewardsSelectItem.size(); i++)
    {
        RewardsSelectItem[i]->Save(writer);
    }

    writer->Write(FinishNPCIndex);
}

QuestIcon ClientQuestInfo::GetQuestIcon(bool taken, bool completed)
{
    QuestIcon icon = QuestIcon::None;

    switch (Type)
    {
        case QuestType::General:
        case QuestType::Repeatable:
            if (completed)
            {
                icon = QuestIcon::QuestionYellow;
            }
            else if (taken)
            {
                icon = QuestIcon::QuestionWhite;
            }
            else
            {
                icon = QuestIcon::ExclamationYellow;
            }
            break;
        case QuestType::Daily:
            if (completed)
            {
                icon = QuestIcon::QuestionBlue;
            }
            else if (taken)
            {
                icon = QuestIcon::QuestionWhite;
            }
            else
            {
                icon = QuestIcon::ExclamationBlue;
            }
            break;
        case QuestType::Story:
            if (completed)
            {
                icon = QuestIcon::QuestionGreen;
            }
            else if (taken)
            {
                icon = QuestIcon::QuestionWhite;
            }
            else
            {
                icon = QuestIcon::ExclamationGreen;
            }
            break;
    }

    return icon;
}

QuestIcon ClientQuestProgress::getIcon() const
{
    return QuestInfo->GetQuestIcon(Taken, Completed);
}

ClientQuestProgress::ClientQuestProgress()
{
}

ClientQuestProgress::ClientQuestProgress(BinaryReader *reader)
{
    Id = reader->ReadInt32();

    int count = reader->ReadInt32();

    for (int i = 0; i < count; i++)
    {
        TaskList.push_back(reader->ReadString());
    }

    Taken = reader->ReadBoolean();
    Completed = reader->ReadBoolean();
    New = reader->ReadBoolean();
}

void ClientQuestProgress::Save(BinaryWriter *writer)
{
    writer->Write(Id);

    writer->Write(TaskList.size());

    for (int i = 0; i < TaskList.size(); i++)
    {
        writer->Write(TaskList[i]);
    }

    writer->Write(Taken);
    writer->Write(Completed);
    writer->Write(New);
}

ClientBuff::ClientBuff()
{
    Stats = new Stats();
}

ClientBuff::ClientBuff(BinaryReader *reader)
{
    Caster = "";

    Type = static_cast<BuffType>(reader->ReadByte());
    Visible = reader->ReadBoolean();
    ObjectID = reader->ReadUInt32();
    ExpireTime = reader->ReadInt64();
    Infinite = reader->ReadBoolean();

    Stats = new Stats(reader);

    int count = reader->ReadInt32();

    Values = std::vector<int>(count);

    for (int i = 0; i < count; i++)
    {
        Values[i] = reader->ReadInt32();
    }
}

void ClientBuff::Save(BinaryWriter *writer)
{
    writer->Write(static_cast<unsigned char>(Type));
    writer->Write(Visible);
    writer->Write(ObjectID);
    writer->Write(ExpireTime);
    writer->Write(Infinite);

    Stats->Save(writer);

    writer->Write(Values.size());
    for (int i = 0; i < Values.size(); i++)
    {
        writer->Write(Values[i]);
    }
}
